const { think } = require('thinkjs');
const Base = require('./base.js');
const moment = require('moment');
const crypto = require('crypto');
const cid = require('@4a/cid');
const { default: BigNumber } = require('bignumber.js');

module.exports = class extends Base {
  /**
   * 生成签名字符串
   * @param {Object} data 参数对象
   * @param {String} nonce 随机字符串
   * @returns {String} 签名字符串
   */
  getSign(data, nonce) {
    // 获取关键字列表并排序
    const keys = Object.keys(data).sort();
    let signStr = '';

    // 拼接所有value值
    for (const key of keys) {
      signStr += data[key];
    }

    // 加上随机字符串
    signStr += nonce;

    // 计算MD5值
    return this.getMD5(signStr);
  }

  /**
   * MD5加密
   * @param {String} text 要加密的文本
   * @returns {String} 32位小写MD5字符串
   */
  getMD5(text) {
    const hash = crypto.createHash('md5');
    hash.update(text, 'utf8');
    return hash.digest('hex');
  }

  async checkChengbenAction() {
    await this.model('jisuan').jiafang(this.get('id'));
    return this.success();
  }
  async checkChengbenLogAction() {
    await this.model('jisuan').contractLog();
    return this.success();
  }
  async checkTaxAction() {
    const current = moment().format('YYYY-MM');
    const prev = moment()
      .subtract(1, 'month')
      .format('YYYY-MM');
    const has = await this.model('tax_list')
      .where({ month: current })
      .find();
    if (think.isEmpty(has)) {
      const list = await this.model('account_list').select();
      await this.model('tax_list')
        .where({ month: prev })
        .update({
          status: 1,
        });
      for (const item of list) {
        await this.model('tax_list').add({
          create_time: ['exp', 'CURRENT_TIMESTAMP()'],
          month: current,
          account_id: item.id,
        });
      }
    }

    return this.success();
  }
  async checkStaffAction() {
    const current = moment().format('YYYY-MM');

    const has = await this.model('output_list')
      .where({ month: current, type: 'staff' })
      .find();
    if (think.isEmpty(has)) {
      await this.model('output_list').add({
        update_time: moment().format('YYYY-MM-DD'),
        month: current,
        type: 'staff',
        account_id: 128,
      });
    }

    return this.success();
  }
  async checkContractAction() {
    const data = await this.model('contract_list')
      .where({ status: 1, type: ['IN', [1, 2]] })
      .select();
    for (const item of data) {
      if (item.date_end) {
        if (moment(item.date_end).isBefore(moment())) {
          await this.model('contract_list')
            .where({ id: item.id })
            .update({ status: 2 });
          // if (item.contract_type === 70) {
          //   this.model('guakao_list').where({})
          // }
          if (item.type === 1) {
            const projectInfo = JSON.parse(item.project);
            for (const item of projectInfo) {
              await this.model('project_list')
                .where({
                  id: item[3],
                })
                .update({
                  status: 3,
                });
            }
          }
        }
      }
    }

    const dataPass = await this.model('contract_list')
      .where({ status: 3, type: ['IN', [1, 2]] })
      .select();
    for (const item of dataPass) {
      await this.model('income_list')
        .where({ contract_id: item.id })
        .update({ pass: 1 });
    }
    return this.success();
  }
  async checkDelayAction() {
    const dataIn = await this.model('income_list')
      .where({ status: 0 })
      .select();
    for (const item of dataIn) {
      if (item.remind_date) {
        if (moment(item.remind_date).isBefore(moment())) {
          await this.model('income_list')
            .where({ id: item.id })
            .update({ delay: 1 });
        } else {
          await this.model('income_list')
            .where({ id: item.id })
            .update({ delay: 0 });
        }
      }
    }
    const dataOut = await this.model('output_list')
      .where({ status: 0 })
      .select();
    for (const item of dataOut) {
      if (item.remind_date) {
        if (moment(item.remind_date).isBefore(moment())) {
          await this.model('output_list')
            .where({ id: item.id })
            .update({ delay: 1 });
        } else {
          await this.model('output_list')
            .where({ id: item.id })
            .update({ delay: 0 });
        }
      }
    }
    return this.success();
  }

  async checkChaobiaoAction() {
    const dbs = await this.model('ac_db')
      .where({
        type: ['IN', ['电表', '空调']],
      })
      .field('collect, db_id')
      .select();

    const request_content = [];

    for (const item of dbs) {
      request_content.push({
        opr_id: cid(16, { prefix: 'OP' }),
        cid: item.collect,
        address: item.db_id,
        type: 3,
      });
    }
    this.model('ac_db_log').addMany(request_content);
    const data = await this.service('db', 'admin').chaobiao(request_content);
    return this.success(data);
  }
  async getChaobiaoAction() {
    const values = this.post();

    try {
      // 解析response_content
      const responseContent = JSON.parse(values.response_content);

      // 验证签名
      const sign = this.getSign(
        {
          timestamp: values.timestamp,
          response_content: values.response_content,
        },
        'kJNdHdFdTsn4XuLfgeJO9Vk'
      );

      if (sign !== values.sign) {
        return this.fail('签名验证失败');
      }

      // 处理所有抄表数据
      const meterDataList = responseContent.map((result) => {
        if (result.status === 'SUCCESS') {
          const meterData = result.data[0];
          const valueV2 = meterData.value_v2;

          return {
            opr_id: result.opr_id,
            resolve_time: result.resolve_time,
            // status: result.status,
            // 基础数据
            // type: meterData.type, // 抄表类型
            // value: meterData.value, // 抄表值
            // 电表数据
            total_power: valueV2.zhygzdl, // 总有功总电量
            // voltage: {
            //   a: valueV2.axdy,
            //   b: valueV2.bxdy,
            //   c: valueV2.cxdy
            // },
            // current: {
            //   a: valueV2.axdl,
            //   b: valueV2.bxdl,
            //   c: valueV2.cxdl
            // },
            // power_factor: valueV2.zglys, // 总功率因数
            // frequency: valueV2.pl, // 频率
            // temperature: valueV2.wd, // 温度
            // meter_status: valueV2.dbzt, // 电表状态
            // // 其他重要数据
            // settlement_type: valueV2.jsfs, // 结算方式
            // rate_number: valueV2.fls, // 费率数
            // phase_type: valueV2.xs, // 相数
            // active_power: valueV2.zyggl, // 总有功功率
            // reactive_power: valueV2.zwggl, // 总无功功率
            // apparent_power: valueV2.zszgl, // 总视在功率
            // raw_data: valueV2 // 原始数据
          };
        } else {
          return {
            opr_id: result.opr_id,
            resolve_time: result.resolve_time,
            total_power: null,
            error: '抄表失败',
          };
        }
      });
      // 更新数据库
      for (const data of meterDataList) {
        await this.model('ac_db_log')
          .where({ opr_id: data.opr_id })
          .update(data);
      }

      return this.success(meterDataList);
    } catch (error) {
      console.error('处理抄表回调数据出错:', error);
      return this.fail('处理数据出错');
    }
  }

  async checkShuibiaoAction() {
    const dbs = await this.model('ac_db')
      .where({
        type: ['IN', ['水表']],
      })
      .field('collect, db_id')
      .select();

    const request_content = [];

    for (const item of dbs) {
      request_content.push({
        opr_id: cid(16, { prefix: 'OP' }),
        cid: item.collect,
        address: item.db_id,
        type: 42,
      });
    }
    this.model('ac_db_log').addMany(request_content);
    const data = await this.service('db', 'admin').shuibiao(request_content);
    return this.success(data);
  }
  async getShuibiaoAction() {
    const values = this.post();

    try {
      // 解析response_content
      const responseContent = JSON.parse(values.response_content);

      // 验证签名
      const sign = this.getSign(
        {
          timestamp: values.timestamp,
          response_content: values.response_content,
        },
        'kJNdHdFdTsn4XuLfgeJO9Vk'
      );

      if (sign !== values.sign) {
        return this.fail('签名验证失败');
      }

      // 处理所有抄表数据
      const meterDataList = responseContent.map((result) => {
        if (result.status === 'SUCCESS') {
          const meterData = result.data[0];
          const valueV2 = meterData.value;

          return {
            opr_id: result.opr_id,
            resolve_time: result.resolve_time,
            // status: result.status,
            // 基础数据
            // type: meterData.type, // 抄表类型
            // value: meterData.value, // 抄表值
            // 电表数据
            total_power: valueV2[0], // 总有功总电量
            // voltage: {
            //   a: valueV2.axdy,
            //   b: valueV2.bxdy,
            //   c: valueV2.cxdy
            // },
            // current: {
            //   a: valueV2.axdl,
            //   b: valueV2.bxdl,
            //   c: valueV2.cxdl
            // },
            // power_factor: valueV2.zglys, // 总功率因数
            // frequency: valueV2.pl, // 频率
            // temperature: valueV2.wd, // 温度
            // meter_status: valueV2.dbzt, // 电表状态
            // // 其他重要数据
            // settlement_type: valueV2.jsfs, // 结算方式
            // rate_number: valueV2.fls, // 费率数
            // phase_type: valueV2.xs, // 相数
            // active_power: valueV2.zyggl, // 总有功功率
            // reactive_power: valueV2.zwggl, // 总无功功率
            // apparent_power: valueV2.zszgl, // 总视在功率
            // raw_data: valueV2 // 原始数据
          };
        } else {
          return {
            opr_id: result.opr_id,
            resolve_time: result.resolve_time,
            total_power: null,
            error: '抄表失败',
          };
        }
      });
      // 更新数据库
      for (const data of meterDataList) {
        await this.model('ac_db_log')
          .where({ opr_id: data.opr_id })
          .update(data);
      }

      return this.success(meterDataList);
    } catch (error) {
      console.error('处理抄表回调数据出错:', error);
      return this.fail('处理数据出错');
    }
  }

  async checkDianfeiMonthAction() {
    const projectId = this.get('project_id') || '2294';
    if (!this.isCli) return this.fail(1000, 'deny');
    const contract_list = await this.model('contract_list')
      .where({
        project_id: projectId,
        dianbiao_list: ['!=', ''],
      })
      .field('dianbiao_list, id')
      .select();
    for (const element of contract_list) {
      const acDbList = await this.model('ac_db')
        .where({ id: ['IN', element.dianbiao_list] })
        .select();
      console.log(acDbList);

      for (const dbItem of acDbList) {
        const logInfo = await this.model('ac_db_log')
          .where({ address: dbItem.db_id, total_power: ['!=', null] })
          .order('opr_id DESC')
          .find();
        console.log(logInfo);

        const logPrev = await this.model('ac_db_log')
          .where({
            address: dbItem.db_id,
            total_power: ['!=', null],
            chaobiao: 1,
          })
          .order('id DESC')
          .find();
        let prev = 0;
        let prevDate = '';
        if (!think.isEmpty(logPrev)) {
          prev = logPrev.total_power;
          prevDate = logPrev.resolve_time;
        }

        await this.model('ac_db_log')
          .where({ opr_id: logInfo.opr_id })
          .update({ chaobiao: 1 });

        const info = {
          current: logInfo.total_power,
          prev: prev,
          ac_id: logInfo.address,
          ac_name: dbItem.remark + '(' + dbItem.type + ')',
        };

        const real_num = BigNumber(logInfo.total_power)
          .minus(BigNumber(prev))
          .toFixed();

        await this.model('income_list').add({
          // month: JSON.stringify([
          //   item.preData.update_time,
          //   item.currentData.update_time,
          // ]),
          shuidian_info: JSON.stringify(info),
          type: 'shuidian',
          project_id: projectId,
          contract_id: element.id,
          create_time: ['exp', 'CURRENT_TIMESTAMP()'],
          circle_start: prevDate,
          circle_end: logInfo.resolve_time,
          status: 0,
          shuidian_type: 1,
          shuidian_num: real_num,
          remark: '电能抄表1号自动结算',
        });
      }
    }

    console.log('执行电费任务');
  }

  async checkTestAction() {
    const item = await this.model('contract_list')
      .where({ id: 5305 })
      .find();

    const arr = JSON.parse(item.project);

    const room = [];
    for (const itemRoom of arr) {
      if (itemRoom[3]) {
        room.push(itemRoom[3]);
      }
    }

    const months = moment(item.date_end)
      .add(1, 'days')
      .diff(moment(item.date_start), 'month');

    if (!item.area_contract) {
      return this.success();
    }

    const zujin = BigNumber(item.fangzu)
      .plus(BigNumber(item.wuye))
      .div(BigNumber(item.area_contract))
      .div(months);

    const roomsData = await this.model('project_list')
      .where({
        id: ['IN', room],
      })
      .select();

    for (const itemRoom of roomsData) {
      const cost = BigNumber(zujin)
        .times(BigNumber(itemRoom.area))
        .plus(itemRoom.zujin);

      console.log(
        cost.toFixed(2),
        77777,
        itemRoom.area,
        888,
        itemRoom.zujin,
        1231231,
        zujin.toFixed(2)
      );

      const origin = await this.model('project_list')
        .where({ id: itemRoom.origin_id })
        .find();

      const chengben = BigNumber(origin.chengben_unit).times(
        BigNumber(itemRoom.area)
      );

      const lirun = cost.minus(BigNumber(chengben)).plus(itemRoom.lirun);

      //甲方合同期限获取
      const floor = await this.model('project_list')
        .where({ type: 3, id: itemRoom.floor_id })
        .find();

      // const monthsJiafang = moment(floor.contract_time_end)
      //   .add(1, 'days')
      //   .diff(moment(floor.contract_time), 'month');

      if (itemRoom.origin_id) {
        const originZujin = BigNumber(origin.zujin).plus(cost);
        const originLirun = BigNumber(origin.lirun).plus(lirun);
        await this.model('project_list')
          .where({ id: itemRoom.origin_id })
          .update({
            lirun: originLirun.toFixed(2),
            zujin: originZujin.toFixed(2),
          });
      }

      if (item.status !== 3) {
        await this.model('project_list')
          .where({ id: itemRoom.id })
          .update({
            lirun: lirun.toFixed(2),
            zujin: cost.toFixed(2),
            shouru_unit: BigNumber(item.fangzu_unit)
              .plus(BigNumber(item.wuye_unit))
              .toFixed(2),
            lirun_unit: BigNumber(item.fangzu_unit)
              .plus(BigNumber(item.wuye_unit))
              .minus(BigNumber(itemRoom.chengben_unit))
              .toFixed(2),
            status: 2,
          });
        await this.model('project_log')
          .where({ contract_id: item.id, room_id: itemRoom.id })
          .delete();
        await this.model('project_log').add({
          project_id: itemRoom.project_id,
          floor_id: itemRoom.floor_id,
          room_id: itemRoom.id,
          area: item.area_contract,
          contract_id: item.id,
          jiafang_start: floor.contract_time,
          jiafang_end: floor.contract_time_end,
          contract_start: item.date_start,
          contract_end: item.date_end,
          rent_start: item.date_start,
          rent_end: item.date_end,
          status: 1,
          lirun: lirun.toFixed(2),
          zujin: cost.toFixed(2),
          zujin_total: BigNumber(zujin)
            .times(BigNumber(itemRoom.area))
            .times(BigNumber(months))
            .toFixed(2),
          chengben: itemRoom.chengben,
          chengben_total: BigNumber(itemRoom.chengben_unit)
            .times(BigNumber(months))
            .times(BigNumber(itemRoom.area))
            .toFixed(2),
        });
      } else {
        const shouru = await this.model('income_list')
          .where({
            contract_id: item.id,
            status: 1,
            type: ['IN', ['fangzu', 'wuye', 'ruzhang', 'bujiao']],
          })
          .sum('money');

        const hasEndContract = await this.model('project_log')
          .where({ contract_id: item.id })
          .find();

        if (think.isEmpty(hasEndContract)) {
          await this.model('project_log').add({
            project_id: itemRoom.project_id,
            floor_id: itemRoom.floor_id,
            room_id: itemRoom.id,
            area: item.area_contract,
            contract_id: item.id,
            jiafang_start: floor.contract_time,
            jiafang_end: floor.contract_time_end,
            contract_start: item.date_start,
            contract_end: item.date_end,
            rent_start: item.date_start,
            rent_end: item.tuizuDate,
            status: 2,
            lirun: lirun.toFixed(2),
            zujin: cost.toFixed(2),
            zujin_total: shouru || 0,
            chengben: itemRoom.chengben,
            chengben_total: BigNumber(itemRoom.chengben_unit)
              .times(BigNumber(months))
              .times(BigNumber(itemRoom.area))
              .toFixed(2),
          });
        } else {
          await this.model('project_log')
            .where({ contract_id: item.id })
            .update({
              status: 2,
              rent_end: item.tuizuDate,
              zujin_total: shouru || 0,
            });
        }
      }
    }
    return this.success();
  }
};
